﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MethodWorx.CMS.TemplateLanguage.Properties;
using MethodWorx.CMS.TemplateLanguage.Design;
using MethodWorx.CMS.Services;
using MethodWorx.CMS.Content;
using MethodWorx.CMS.Plugins.ViewManagement;
using MethodWorx.CMS.Providers;

namespace MethodWorx.CMS.TemplateLanguage.Parsers.Page
{
    public abstract class Pages
    {
        public Pages()
        {
            this.Options = "DirectDescendants";
        }

        [Property(Description="Matches pages based on tags (comma seperated list)")]
        public string Tags { get; set; }

        [Property(Description="Matches pages based on view name")]
        public string View { get; set; }

        [DependencyPropertyAttribute]
        public ContentService ContentService { get; set; }

        [DependencyPropertyAttribute]
        public ICmsDataProvider Provider { get; set; }

        [Property(Description = "DirectDescendants")]
        public string Options { get; set; }

        [Property(Description="Matches pages based on template")]
        public string Template { get; set;}

        [Property(Description="Maximum Results")]
        public int? Maximum { get; set; }


       
        protected IEnumerable<MethodWorx.CMS.Content.Page> GetPages(Web.CmsRequestContext context, MethodWorx.CMS.Content.Page currentPage)
        {
            var results = this.GetPagesInternal(context, currentPage);
            if (this.Maximum.HasValue)
                return results.Take(this.Maximum.Value);
            else
                return results;
        }

        private IEnumerable<MethodWorx.CMS.Content.Page> GetPagesInternal(Web.CmsRequestContext context, MethodWorx.CMS.Content.Page currentPage)
        {
            if (!string.IsNullOrEmpty(this.View))
            {
                var service = new StaticViewService(this.Provider);
                foreach (var sv in service.GetAll())
                {
                    if (sv.Name.ToLower() == this.View.ToLower())
                    {
                        //
                        //  ok, this is the view
                        foreach (Guid id in sv.Ids ?? new Guid[0])
                        {
                            var page = this.ContentService.GetPageById(id);
                            if (page != null)
                                yield return page;
                        }
                    }
                }
            }
            else if (!string.IsNullOrEmpty(this.Tags))
            {
                foreach (var page in this.ContentService.GetPagesByTags(this.Tags))
                    yield return page;
            }
            else
            {
                bool directDescendants = (Options ?? "").ToLower().Split(',').Contains("directdescendants");
                bool allDescendants = (Options ?? "").ToLower().Split(',').Contains("alldescendants");
                bool all = (Options ?? "").ToLower().Split(',').Contains("all");
                if (directDescendants)
                {
                    //  
                    //  ok, we are searching direct descendants
                    foreach (
                        var page in
                            currentPage.ChildPages.Where(
                                cp =>
                                string.IsNullOrEmpty(this.Template) ||
                                cp.Template.Name.ToLower() == this.Template.ToLower()))
                    {
                        yield return page;
                    }
                }
                else if (allDescendants)
                {
                    //  
                    //  ok, we are searching direct descendants
                    foreach (var page in currentPage.AllChildPages.Where(
                                cp =>
                                string.IsNullOrEmpty(this.Template) ||
                                cp.Template.Name.ToLower() == this.Template.ToLower()))
                    {
                        yield return page;
                    }
                }
                else if (!string.IsNullOrEmpty(this.Template) && all)
                {
                    foreach (var page in this.ContentService.GetPagesByTemplate(this.Template))
                        yield return page;
                }
            }
        }

        
    }
}
